1. Related Prior Research
The decomposition and analysis of computer source code patterns is an established idea, and the concept of creating a hierarchy of related patterns has been in the literature almost as long as patterns themselves [9, 17, 29, 37]. The few researchers who have attempted to provide a truly formal basis for patterns have most commonly done so from a desire to perform refactoring of existing code, while others have attempted the more pragmatic approach of identifying core components of existing patterns in use.
Refactoring Approaches
Refactoring [14] has been a frequent target of formalization techniques, with fairly good success to date [10, 22, 25]. The primary motivation of refactoring is to facilitate tool support for, and validation of, transformation of code from one form to another while preserving behavior. This is an important step in the maintenance and alteration of existing systems and patterns are seen as the logical next abstraction upon which they should operate. These approaches, however, have one missing aspect: they lack appropriate flexibility of implementation.
Fragments: As developed by Florijm, Meijers, and van Winsen [13], fragments provide a practical implementation of pattern analysis and coding support in the Smalltalk language and demonstrate the power of application of these concepts. Their fragments are abstractions of a design elements, such as classes, patterns, methods, or code, and contain roles, or slots, which are filled by other fragments. In this way fragments are bound to each other to produce an architecture in much the same way that objects, classes, and such are in a working system, but the single definition of a fragment allows them to work with all components of the system in a singular way. This approach, while successful in assisting an engineer in working with a system, does have some limitations. For example, detection of existing patterns in the system was deemed unlikely, due to the fact that “many conceptual roles did not exist as distinct program elements, but were cluttered onto a few, more complex ones.” This indicates that there may be a lower level of conceptual roles to address, below fragments.
LePuS: Eden's work on LePuS [11] is an excellent example of formalizing a language for pattern description, based on the fragments theory. LePuS lacks a tie to the more traditional formal denotational semantics of language theory, however, severely limiting its usefulness as a unifying system for code analysis. Pattern analysis and metrics are but one portion of the spectrum of tasks associated with system maintenance and design. An exquisitely elegant architecture may in fact be a poor choice for a system where performance or some other criteria is of paramount importance. System architects must have available all the relevant information for their system to be able to appropriately design and maintain it. Legacy systems, in particular, benefit from more procedural-based analysis, including cohesion and coupling metrics, slice analysis, and other data-centric approaches. One goal of the methods and systems described herein is to enhance the tools for refactoring, not only of current object-oriented systems, but of older code that may just now be being converted to an object-oriented approach. It is therefore desirable to incorporate such analysis systems into any pattern analysis framework. To not do so is to further the chasm between the abstract concepts and the concrete code, instead of unifying them, as patterns are designed to do.
Minipatterns: Ó Cinnéide's work in transformation and refactoring of patterns in code [23] is an example of the application of minipatterns, portions of patterns that are used to compose larger bodies. Ó Cinnéide treats the minipatterns as stepping stones along a refactoring path, allowing each to be a discrete unit that can be refactored under a minitransformation, in much the same way that Fowler's refactorings [14] are used to incrementally transform code at and below the object level. These minipatterns are demonstrated to be highly useful for many applications, but cannot capture some of the more dynamic behavior of patterns, instead relying heavily on syntactical constructs for evidence of the minipatterns.
Structural Analyses
An analysis of the ‘Gang of Four’ (GoF) patterns [15] reveals many shared structural and behavioral elements, such as the similarities between Composite and Visitor [15]. Relationships between patterns, such as inclusion or similarity, have been investigated by various practitioners, and a number of meaningful examples of underlying structures have been described [5, 9, 29, 36, 37].
Objectifier: The Objectifier pattern [37] is one such example of a core piece of structure and behavior shared between many more complex patterns. Its intent is to:                objectify similar behavior in additional classes, so that clients can vary such behavior independently from other behavior, thus supporting variation-oriented design. Instances from those classes represent behavior or properties, but not concrete objects from the real world (similar to reification).FIG. 1 is a class diagram illustrating the Objectifier class structure.        
All of the class diagrams illustrated herein are drawn in Unified Modeling Language (UML) format. UML is a standard for graphic modeling of software. Since UML is known to those of skill in the art of computer software development, a detailed description thereof will not be presented herein. The UML standard is described in a number of commercially-available publications, including Fowler, Martin, UML Distilled: A Brief Guide to the Standard Object Modeling Language, Third Edition, Addison-Wesley 2004, the disclosure of which is incorporated herein by reference in its entirety.
Zimmer uses Objectifier as a ‘basic pattern’ in the construction of several other GoF patterns, such as Builder, Observer, Bridge, State, Command and Iterator. It is a simple yet elegantly powerful structural concept that is used repeatedly in other patterns.
Object Recursion: Woolf takes Objectifier one step further, adding a behavioral component, and naming it Object Recursion [36]. FIG. 2 is a class diagram illustrating the Object Recursion class structure. The class diagram in FIG. 2 is extremely similar to Objectifier, with an important difference, namely the behavior in the leaf subclasses of Handler. Exclusive of this method behavior, however, it seems to be an application of Objectifler in a more specific use. Note that Woolf compares Object Recursion to the relevant GoF patterns and deduces that: Iterator, Composite and Decorator can, in many instances, be seen as containing an instance of Object Recursion; Chain of Responsibility and Interpreter do contain Object Recursion as a primary component.
Relationships: Taken together, the above instances of analyzed pattern findings comprise two parts of a larger chain: Object Recursion contains an instance of Objectifler, and both in turn are used by larger patterns. This indicates that there are meaningful relationships between patterns, yet past work has shown that there are more primary forces at work. Buschmann's variants [7], Coplien and others' idioms [4,9,20], and Pree's metapatterns [27] all support this viewpoint. Shull, Melo and Basili's BACKDOOR's [31] dependency on relationships is exemplary of the normal static treatment that arises. It will become evident that these relationships between concepts are a core piece which grant great flexibility to the practitioner implementing patterns in design, through constructs we term isotopes, which will be treated in Section 4 13. A related, but type-based approach that works instead on UML expressed class designs, is Egyed's UML/Analyzer system [12] which uses abstraction inferences to help guide engineers in code discovery. Reiss's PEKOE [28] uses a relational database language for queries and conceptual component definition.
Accordingly, in light of the difficulties associated with conventional source code analysis methods, there exists a need for improved methods and systems for identifying computer program source code constructs.